
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "value_format.h"

Value::Value()
{
}

Value::~Value()
{
    Clean();
}

Value::Value(Value &v)
{
    Copy(&v);
}

void Value::Copy(Value* v)
{
    switch (v->Type())
    {
    case VT_BOOL_ARRAY:
        Reset(v->Num(), v->GetBoolArray());
        break;
    case VT_STRING:
        Reset(v->GetString());
        break;
    case VT_STRING_ARRAY:
        Reset(v->Num(), v->GetStringArray());
        break;
    case VT_INT_ARRAY:
        Reset(v->Num(), v->GetIntArray());
        break;
    case VT_UINT_ARRAY:
        Reset(v->Num(), v->GetUIntArray());
        break;
    case VT_DOUBLE_ARRAY:
        Reset(v->Num(), v->GetDoubleArray());
        break;
    case VT_POINT_ARRAY:
        Reset(v->Num(), v->GetPointArray());
        break;
    case VT_VALUE_ARRAY:
        if (v->Num() > 0)
        {
            ValueType vts[v->Num()];
            for (int32_t i = 0; i < v->Num(); i++)
                vts[i] = v->GetValueArray()[i].Type();
            Reset(v->Num(), vts);
            for (int32_t i = 0; i < v->Num(); i++)
                content.ValueArray[i].Copy(&v->GetValueArray()[i]);
        }
        break;
    default:
        content = v->GetContent();
        type = v->type;
        num = v->num;
        break;
    }
    sep = v->sep;
    zero = v->zero;
}

Value::Value(ValueType vt)
{
    type = vt;
}

Value::Value(bool b)
{
    Reset(b);
}

Value::Value(int32_t num, bool* bArray)
{
    Reset(num, bArray);
}

Value::Value(int32_t num, bool b, ...)
{
    type = VT_BOOL_ARRAY;
    content.BoolArray = new bool[num];

    va_list ap;
    va_start(ap, b);
    content.BoolArray[0] = b;
    for (int32_t i = 1; i < num; i++)
        content.BoolArray[i] = va_arg(ap, int32_t) ? true : false;
    va_end(ap);

    this->num = num;
}

Value::Value(char c)
{
    Reset(c);
}

Value::Value(char* str)
{
    Reset(str);
}

Value::Value(int32_t num, char** strArray)
{
    Reset(num, strArray);
}

Value::Value(int32_t num, char* str, ...)
{
    type = VT_STRING_ARRAY;
    content.StringArray = new char*[num]();

    va_list ap;
    va_start(ap, str);

    int32_t len = str ? strlen(str) : 0;
    content.StringArray[0] = new char[len + 1]();
    if (str) strcpy(content.StringArray[0], str);

    for (int32_t i = 1; i < num; i++)
    {
        str = va_arg(ap, char* );
        len = str ? strlen(str) : 0;
        content.StringArray[i] = new char[len + 1]();
        if (str) strcpy(content.StringArray[i], str);
    }
    va_end(ap);

    this->num = num;
}

Value::Value(int32_t i)
{
    Reset(i);
}

Value::Value(int32_t num, int32_t* iArray)
{
    Reset(num, iArray);
}

Value::Value(int32_t num, int32_t i, ...)
{
    type = VT_INT_ARRAY;
    content.IntArray = new int32_t[num];

    va_list ap;
    va_start(ap, i);
    content.IntArray[0] = i;
    for (int32_t i = 1; i < num; i++)
        content.IntArray[i] = va_arg(ap, int32_t);
    va_end(ap);

    this->num = num;
}

Value::Value(uint32_t ui)
{
    Reset(ui);
}

Value::Value(int32_t num, uint32_t* uiArray)
{
    Reset(num, uiArray);
}

Value::Value(int32_t num, uint32_t ui, ...)
{
    type = VT_UINT_ARRAY;
    content.UIntArray = new uint32_t[num];

    va_list ap;
    va_start(ap, ui);
    content.UIntArray[0] = ui;
    for (int32_t i = 1; i < num; i++)
        content.UIntArray[i] = va_arg(ap, uint32_t);
    va_end(ap);

    this->num = num;
}

Value::Value(double d)
{
    Reset(d);
}

Value::Value(int32_t num, double* fArray)
{
    Reset(num, fArray);
}

Value::Value(int32_t num, double d, ...)
{
    type = VT_DOUBLE_ARRAY;
    content.DoubleArray = new double[num];

    va_list ap;
    va_start(ap, d);
    content.DoubleArray[0] = d;
    for (int32_t i = 1; i < num; i++)
        content.DoubleArray[i] = va_arg(ap, double);
    va_end(ap);

    this->num = num;
}

Value::Value(void* p)
{
    Reset(p);
}

Value::Value(int32_t num, void** pArray)
{
    Reset(num, pArray);
}

Value::Value(int32_t num, void* p, ...)
{
    type = VT_POINT_ARRAY;
    content.PointArray = new void*[num]();

    va_list ap;
    va_start(ap, p);
    content.PointArray[0] = p;
    for (int32_t i = 1; i < num; i++)
        content.PointArray[i] = va_arg(ap, void* );
    va_end(ap);

    this->num = num;
}

Value::Value(int32_t num, ValueType* vtArray)
{
    Reset(num, vtArray);
}

Value::Value(int32_t num, ValueType vt, ...)
{
    type = VT_VALUE_ARRAY;
    content.ValueArray = new Value[num];

    va_list ap;
    va_start(ap, vt);
    content.ValueArray[0].type = vt;
    if (content.ValueArray[0].type < VT_BOOL_ARRAY)
        content.ValueArray[0].num = 1;
    for (int32_t i = 1; i < num; i++)
    {
        content.ValueArray[i].type = (ValueType)va_arg(ap, int32_t);
        if (content.ValueArray[i].type < VT_BOOL_ARRAY)
            content.ValueArray[i].num = 1;
    }
    va_end(ap);

    this->num = num;
}

void Value::Reset(bool b)
{
    Clean();
    type = VT_BOOL;
    content.Bool = b;
    num = 1;
}

void Value::Reset(int32_t num, bool* bArray)
{
    Clean();
    type = VT_BOOL_ARRAY;
    content.BoolArray = new bool[num];
    for (int32_t i = 0; i < num; i++)
        content.BoolArray[i] = bArray[i];
    this->num = num;
}

void Value::Reset(int32_t num, bool b, ...)
{
    Clean();
    type = VT_BOOL_ARRAY;
    content.BoolArray = new bool[num];

    va_list ap;
    va_start(ap, b);
    content.BoolArray[0] = b;
    for (int32_t i = 1; i < num; i++)
        content.BoolArray[i] = va_arg(ap, int32_t) ? true : false;
    va_end(ap);

    this->num = num;
}

void Value::Reset(char c)
{
    Clean();
    type = VT_CHAR;
    content.Char = c;
    num = 1;
}

void Value::Reset(char* str)
{
    Clean();
    type = VT_STRING;
    content.String = new char[(str ? strlen(str) : 0) + 1]();
    if (str) strcpy(content.String, str);
    this->num = 1;
}

void Value::Reset(int32_t num, char** strArray)
{
    Clean();
    type = VT_STRING_ARRAY;
    content.StringArray = new char*[num]();
    for (int32_t i = 0; i < num; i++)
    {
        int32_t len = strArray[i] ? strlen(strArray[i]) : 0;
        content.StringArray[i] = new char[len + 1]();
        if (strArray[i]) strcpy(content.StringArray[i], strArray[i]);
    }
    this->num = num;
}

void Value::Reset(int32_t num, char* str, ...)
{
    Clean();
    type = VT_STRING_ARRAY;
    content.StringArray = new char*[num]();

    va_list ap;
    va_start(ap, str);

    int32_t len = str ? strlen(str) : 0;
    content.StringArray[0] = new char[len + 1]();
    if (str) strcpy(content.StringArray[0], str);

    for (int32_t i = 1; i < num; i++)
    {
        str = va_arg(ap, char* );
        len = str ? strlen(str) : 0;
        content.StringArray[i] = new char[len + 1]();
        if (str) strcpy(content.StringArray[i], str);
    }
    va_end(ap);

    this->num = num;
}

void Value::Reset(int32_t i)
{
    Clean();
    type = VT_INT;
    content.Int = i;
    num = 1;
}

void Value::Reset(int32_t num, int32_t* iArray)
{
    Clean();
    type = VT_INT_ARRAY;
    content.IntArray = new int32_t[num];
    for (int32_t i = 0; i < num; i++)
        content.IntArray[i] = iArray[i];
    this->num = num;
}

void Value::Reset(int32_t num, int32_t i, ...)
{
    Clean();
    type = VT_INT_ARRAY;
    content.IntArray = new int32_t[num];

    va_list ap;
    va_start(ap, i);
    content.IntArray[0] = i;
    for (int32_t i = 1; i < num; i++)
        content.IntArray[i] = va_arg(ap, int32_t);
    va_end(ap);

    this->num = num;
}

void Value::Reset(uint32_t ui)
{
    Clean();
    type = VT_UINT;
    content.UInt = ui;
    num = 1;
}

void Value::Reset(int32_t num, uint32_t* uiArray)
{
    Clean();
    type = VT_UINT_ARRAY;
    content.UIntArray = new uint32_t[num];
    for (int32_t i = 0; i < num; i++)
        content.UIntArray[i] = uiArray[i];
    this->num = num;
}

void Value::Reset(int32_t num, uint32_t ui, ...)
{
    Clean();
    type = VT_UINT_ARRAY;
    content.UIntArray = new uint32_t[num];

    va_list ap;
    va_start(ap, ui);
    content.UIntArray[0] = ui;
    for (int32_t i = 1; i < num; i++)
        content.UIntArray[i] = va_arg(ap, uint32_t);
    va_end(ap);

    this->num = num;
}

void Value::Reset(double d)
{
    Clean();
    type = VT_DOUBLE;
    content.Double = d;
    num = 1;
}

void Value::Reset(int32_t num, double* fArray)
{
    Clean();
    type = VT_DOUBLE_ARRAY;
    content.DoubleArray = new double[num];
    for (int32_t i = 0; i < num; i++)
        content.DoubleArray[i] = fArray[i];
    this->num = num;
}

void Value::Reset(int32_t num, double d, ...)
{
    Clean();
    type = VT_DOUBLE_ARRAY;
    content.DoubleArray = new double[num];

    va_list ap;
    va_start(ap, d);
    content.DoubleArray[0] = d;
    for (int32_t i = 1; i < num; i++)
        content.DoubleArray[i] = va_arg(ap, double);
    va_end(ap);

    this->num = num;
}

void Value::Reset(void* p)
{
    Clean();
    type = VT_POINT;
    content.Point = p;
    num = 1;
}

void Value::Reset(int32_t num, void** pArray)
{
    Clean();
    type = VT_POINT_ARRAY;
    content.PointArray = new void*[num]();
    for (int32_t i = 0; i < num; i++)
        content.PointArray[i] = pArray[i];
    this->num = num;
}

void Value::Reset(int32_t num, void* p, ...)
{
    Clean();
    type = VT_POINT_ARRAY;
    content.PointArray = new void*[num]();

    va_list ap;
    va_start(ap, p);
    content.PointArray[0] = p;
    for (int32_t i = 1; i < num; i++)
        content.PointArray[i] = va_arg(ap, void* );
    va_end(ap);

    this->num = num;
}

void Value::Reset(int32_t num, ValueType* vtArray)
{
    Clean();
    type = VT_VALUE_ARRAY;
    content.ValueArray = new Value[num];
    for (int32_t i = 0; i < num; i++)
    {
        content.ValueArray[i].type = vtArray[i];
        if (vtArray[i] < VT_BOOL_ARRAY)
            content.ValueArray[i].num = 1;
    }
    this->num = num;
}

void Value::Reset(int32_t num, ValueType vt, ...)
{
    Clean();
    type = VT_VALUE_ARRAY;
    content.ValueArray = new Value[num];

    va_list ap;
    va_start(ap, vt);
    content.ValueArray[0].type = vt;
    for (int32_t i = 1; i < num; i++)
    {
        content.ValueArray[i].type = (ValueType)va_arg(ap, int32_t);
        if (content.ValueArray[i].type < VT_BOOL_ARRAY)
            content.ValueArray[i].num = 1;
    }
    va_end(ap);

    this->num = num;
}

bool& Value::GetBool()
{
    return content.Bool;
}

bool* Value::GetBoolArray()
{
    return content.BoolArray;
}

char& Value::GetChar()
{
    return content.Char;
}

char* Value::GetString()
{
    return content.String;
}

char** Value::GetStringArray()
{
    return content.StringArray;
}

int32_t& Value::GetInt()
{
    return content.Int;
}

int32_t* Value::GetIntArray()
{
    return content.IntArray;
}

uint32_t& Value::GetUInt()
{
    return content.UInt;
}

uint32_t* Value::GetUIntArray()
{
    return content.UIntArray;
}

double& Value::GetDouble()
{
    return content.Double;
}

double* Value::GetDoubleArray()
{
    return content.DoubleArray;
}

void* Value::GetPoint()
{
    return content.Point;
}

void** Value::GetPointArray()
{
    return content.PointArray;
}

Value* Value::GetValueArray()
{
    return content.ValueArray;
}

ValueContent Value::GetContent()
{
    return content;
}

int32_t Value::ArrayAdd(bool b)
{
    if (type != VT_BOOL_ARRAY) {
        Value v(b);
        return ArrayAdd(&v);
    }
    
    bool* bak = content.BoolArray;
    content.BoolArray = new bool[num + 1];

    int32_t i = 0;
    for (; i < num; i++)
        content.BoolArray[i] = bak[i];
    content.BoolArray[i] = b;

    num += 1;
    if (bak) delete[] bak;
    return 0;
}

int32_t Value::ArrayAdd(char* str)
{
    if (type != VT_STRING_ARRAY) {
        Value v(str);
        return ArrayAdd(&v);
    }
    
    char** bak = content.StringArray;
    content.StringArray = new char*[num + 1]();

    int32_t i = 0;
    for (; i < num; i++)
        content.StringArray[i] = bak[i];
    content.StringArray[i] = new char[str ? (strlen(str) + 1) : 1]();
    if (str) strcpy(content.StringArray[i], str);

    num += 1;
    if (bak) delete[] bak;
    return 0;
}

int32_t Value::ArrayAdd(int32_t i)
{
    if (type != VT_INT_ARRAY) {
        Value v(i);
        return ArrayAdd(&v);
    }
    
    int32_t* bak = content.IntArray;
    content.IntArray = new int32_t[num + 1];

    int32_t c = 0;
    for (; c < num; c++)
        content.IntArray[c] = bak[c];
    content.IntArray[c] = i;

    num += 1;
    if (bak) delete[] bak;
    return 0;
}

int32_t Value::ArrayAdd(uint32_t ui)
{
    if (type != VT_UINT_ARRAY) {
        Value v(ui);
        return ArrayAdd(&v);
    }
    
    uint32_t* bak = content.UIntArray;
    content.UIntArray = new uint32_t[num + 1];

    int32_t i = 0;
    for (; i < num; i++)
        content.UIntArray[i] = bak[i];
    content.UIntArray[i] = ui;

    num += 1;
    if (bak) delete[] bak;
    return 0;
}

int32_t Value::ArrayAdd(double d)
{
    if (type != VT_DOUBLE_ARRAY) {
        Value v(d);
        return ArrayAdd(&v);
    }
    
    double* bak = content.DoubleArray;
    content.DoubleArray = new double[num + 1];

    int32_t i = 0;
    for (; i < num; i++)
        content.DoubleArray[i] = bak[i];
    content.DoubleArray[i] = d;

    num += 1;
    if (bak) delete[] bak;
    return 0;
}

int32_t Value::ArrayAdd(void* p)
{
    if (type != VT_POINT_ARRAY) {
        Value v(p);
        return ArrayAdd(&v);
    }
    
    void** bak = content.PointArray;
    content.PointArray = new void*[num + 1];

    int32_t i = 0;
    for (; i < num; i++)
        content.PointArray[i] = bak[i];
    content.PointArray[i] = p;

    num += 1;
    if (bak) delete[] bak;
    return 0;
}

int32_t Value::ArrayAdd(Value* v)
{
    if (type != VT_VALUE_ARRAY)
        ToValueArray();

    Value* bak = content.ValueArray;
    content.ValueArray = new Value[num + 1];

    int32_t i = 0;
    for (; i < num; i++)
        content.ValueArray[i].Copy(&bak[i]);
    content.ValueArray[i].Copy(v);

    num += 1;
    if (bak) delete[] bak;
    return 0;
}

ValueType Value::Type()
{
    return type;
}

char& Value::Sep()
{
    return sep;
}

int32_t& Value::Zero()
{
    return zero;
}

int32_t Value::Num()
{
    return num;
}

void Value::Print(int32_t buffSize)
{
    char* str = new char[buffSize + 1]();
    if (!str)
        return;
    GetPrint(str, buffSize);
    printf("%s\r\n", str);
    delete[] str;
}

void Value::PrintJson(int32_t buffSize)
{
    char* str = new char[buffSize + 1]();
    if (!str)
        return;
    GetPrintJson(str, buffSize);
    printf("%s\r\n", str);
    delete[] str;
}

int32_t Value::GetPrint(char* buff, int32_t buffSize)
{
    int32_t buffSizeRd = buffSize;
    int32_t ret;
    char fmt[32] = {};

    switch (type)
    {
    case VT_BOOL:
        return snprintf(buff, buffSize, "%s%c", content.Bool ? "True" : "False", sep) - (sep ? 0 : 1);

    case VT_BOOL_ARRAY:
        for (int32_t i = 0; i < num && buffSizeRd > 0; i++)
        {
            ret = snprintf(buff, buffSizeRd, "%s%c", content.BoolArray[i] ? "True" : "False", sep) - (sep ? 0 : 1);
            buffSizeRd -= ret;
            buff += ret;
        }
        if (num > 1 && sep) //对于数组,最后一个分隔符是多余的
        {
           * (--buff) = 0;
            buffSizeRd += 1;
        }
        return buffSize - buffSizeRd;

    case VT_CHAR:
        return snprintf(buff, buffSize, "%c%c", content.Char, sep) - (sep ? 0 : 1);

    case VT_STRING:
        return snprintf(buff, buffSize, "%s%c", content.String, sep) - (sep ? 0 : 1);

    case VT_STRING_ARRAY:
        for (int32_t i = 0; i < num && buffSizeRd > 0; i++)
        {
            ret = snprintf(buff, buffSizeRd, "%s%c", content.StringArray[i], sep) - (sep ? 0 : 1);
            buffSizeRd -= ret;
            buff += ret;
        }
        if (num > 1 && sep) //对于数组,最后一个分隔符是多余的
        {
           * (--buff) = 0;
            buffSizeRd += 1;
        }
        return buffSize - buffSizeRd;

    case VT_INT:
    case VT_UINT:
        if (zero > 0)
            snprintf(fmt, sizeof(fmt), "%%0%dd%%c", zero);
        else
            strcpy(fmt, "%d%c");
        return snprintf(buff, buffSize, fmt, content.Int, sep) - (sep ? 0 : 1);

    case VT_INT_ARRAY:
    case VT_UINT_ARRAY:
        if (zero > 0)
            snprintf(fmt, sizeof(fmt), "%%0%dd%%c", zero);
        else
            strcpy(fmt, "%d%c");
        for (int32_t i = 0; i < num && buffSizeRd > 0; i++)
        {
            ret = snprintf(buff, buffSizeRd, fmt, content.IntArray[i], sep) - (sep ? 0 : 1);
            buffSizeRd -= ret;
            buff += ret;
        }
        if (num > 1 && sep) //对于数组,最后一个分隔符是多余的
        {
           * (--buff) = 0;
            buffSizeRd += 1;
        }
        return buffSize - buffSizeRd;

    case VT_DOUBLE:
        if (zero > 0)
            snprintf(fmt, sizeof(fmt), "%%.%df%%c", zero);
        else
            strcpy(fmt, "%f%c");
        return snprintf(buff, buffSize, fmt, content.Double, sep) - (sep ? 0 : 1);

    case VT_DOUBLE_ARRAY:
        if (zero > 0)
            snprintf(fmt, sizeof(fmt), "%%.%df%%c", zero);
        else
            strcpy(fmt, "%f%c");
        for (int32_t i = 0; i < num && buffSizeRd > 0; i++)
        {
            ret = snprintf(buff, buffSizeRd, fmt, content.DoubleArray[i], sep) - (sep ? 0 : 1);
            buffSizeRd -= ret;
            buff += ret;
        }
        if (num > 1 && sep) //对于数组,最后一个分隔符是多余的
        {
           * (--buff) = 0;
            buffSizeRd += 1;
        }
        return buffSize - buffSizeRd;

    case VT_POINT:
        return snprintf(buff, buffSize, "%p%c", content.Point, sep) - (sep ? 0 : 1);

    case VT_POINT_ARRAY:
        for (int32_t i = 0; i < num && buffSizeRd > 0; i++)
        {
            ret = snprintf(buff, buffSizeRd, "%p%c", content.PointArray[i], sep) - (sep ? 0 : 1);
            buffSizeRd -= ret;
            buff += ret;
        }
        if (num > 1 && sep) //对于数组,最后一个分隔符是多余的
        {
           * (--buff) = 0;
            buffSizeRd += 1;
        }
        return buffSize - buffSizeRd;

    case VT_VALUE_ARRAY:
        for (int32_t i = 0; i < num && buffSizeRd > 0; i++)
        {
            ret = content.ValueArray[i].GetPrint(buff, buffSizeRd);
            buffSizeRd -= ret;
            buff += ret;
            if (sep)
            {
                buffSizeRd -= 1;
               * buff++ = sep;
            }
        }
        if (num > 1 && sep) //对于数组,最后一个分隔符是多余的
        {
           * (--buff) = 0;
            buffSizeRd += 1;
        }
        return buffSize - buffSizeRd;

    default:
        return 0;
    }
}

int32_t Value::GetPrintJson(char* buff, int32_t buffSize)
{
    int32_t buffSizeRd = buffSize;
    int32_t ret;

    if (num < 1)
        return snprintf(buff, buffSizeRd, "{}");

    *buff++ = '{';
    buffSizeRd -= 1;

    switch (type)
    {
    case VT_BOOL:
        ret = snprintf(buff, buffSizeRd, "\"0\":%s}", content.Bool ? "true" : "false");
        buffSizeRd -= ret;
        buff += ret;
        break;

    case VT_BOOL_ARRAY:
        for (int32_t i = 0; i < num && buffSizeRd > 0; i++)
        {
            ret = snprintf(buff, buffSizeRd, "\"%d\":%s,", i, content.BoolArray[i] ? "true" : "false");
            buffSizeRd -= ret;
            buff += ret;
        }
        break;

    case VT_CHAR:
        ret = snprintf(buff, buffSizeRd, "\"0\":\"%c\"}", content.Char);
        buffSizeRd -= ret;
        buff += ret;
        break;

    case VT_STRING:
        ret = snprintf(buff, buffSizeRd, "\"0\":\"%s\"}", content.String);
        buffSizeRd -= ret;
        buff += ret;
        break;

    case VT_STRING_ARRAY:
        buffSizeRd -= 1;
        for (int32_t i = 0; i < num && buffSizeRd > 0; i++)
        {
            ret = snprintf(buff, buffSizeRd, "\"%d\":\"%s\",", i, content.StringArray[i]);
            buffSizeRd -= ret;
            buff += ret;
        }
        break;

    case VT_INT:
    case VT_UINT:
        ret = snprintf(buff, buffSizeRd, "\"0\":%d}", content.Int);
        buffSizeRd -= ret;
        buff += ret;
        break;

    case VT_INT_ARRAY:
    case VT_UINT_ARRAY:
        for (int32_t i = 0; i < num && buffSizeRd > 0; i++)
        {
            ret = snprintf(buff, buffSizeRd, "\"%d\":%d,", i, content.IntArray[i]);
            buffSizeRd -= ret;
            buff += ret;
        }
        break;

    case VT_DOUBLE:
        ret = snprintf(buff, buffSizeRd, "\"0\":%lf}", content.Double);
        buffSizeRd -= ret;
        buff += ret;
        break;

    case VT_DOUBLE_ARRAY:
        for (int32_t i = 0; i < num && buffSizeRd > 0; i++)
        {
            ret = snprintf(buff, buffSizeRd, "\"%d\":%lf,", i, content.DoubleArray[i]);
            buffSizeRd -= ret;
            buff += ret;
        }
        break;

    case VT_POINT:
        ret = snprintf(buff, buffSizeRd, "\"0\":\"%p\"}", content.Point);
        buffSizeRd -= ret;
        buff += ret;
        break;

    case VT_POINT_ARRAY:
        for (int32_t i = 0; i < num && buffSizeRd > 0; i++)
        {
            ret = snprintf(buff, buffSizeRd, "\"%d\":\"%p\",", i, content.PointArray[i]);
            buffSizeRd -= ret;
            buff += ret;
        }
        break;

    case VT_VALUE_ARRAY:
        for (int32_t i = 0; i < num && buffSizeRd > 0; i++)
        {
            ret = snprintf(buff, buffSizeRd, "\"%d\":", i);
            buffSizeRd -= ret;
            buff += ret;

            ret = content.ValueArray[i].GetPrintJson(buff, buffSizeRd);
            buffSizeRd -= ret;
            buff += ret;

            *buff++ = ',';
            buffSizeRd -= 1;
        }
        break;

    default:
        *buff++ = '}';
        buffSizeRd -= 1;
        break;
    }

    if (*--buff == ',')
        *buff++ = '}';
    else if (*buff != '}')
    {
        *++buff = '}';
        buffSizeRd -= 1;
    }
    return buffSize - buffSizeRd;
}

void Value::Clean()
{
    switch (type)
    {
    case VT_BOOL_ARRAY:
        if (content.BoolArray)
            delete[] content.BoolArray;
        break;
    case VT_STRING:
        if (content.String)
            delete[] content.String;
        break;
    case VT_STRING_ARRAY:
        if (content.StringArray)
        {
            for (int32_t i = 0; i < num; i++)
            {
                if (content.StringArray[i])
                    delete[] content.StringArray[i];
            }
            delete[] content.StringArray;
        }
        break;
    case VT_INT_ARRAY:
        if (content.IntArray)
            delete[] content.IntArray;
        break;
    case VT_UINT_ARRAY:
        if (content.UIntArray)
            delete[] content.UIntArray;
        break;
    case VT_DOUBLE_ARRAY:
        if (content.DoubleArray)
            delete[] content.DoubleArray;
        break;
    case VT_POINT_ARRAY:
        if (content.PointArray)
            delete[] content.PointArray;
        break;
    case VT_VALUE_ARRAY:
        if (content.ValueArray)
            delete[] content.ValueArray;
        break;
    default:
        break;
    }

    memset(&content, 0, sizeof(ValueContent));
    type = VT_BOOL;
    sep = 0;
    zero = 0;
    num = 0;
}

void Value::ToValueArray()
{
    ValueContent bakContent = content;
    ValueType bakType = type;

    type = VT_VALUE_ARRAY;

    //这里就返回了,如果bakContent中有未释放内存如何?
    if (num < 1)
    {
        content.ValueArray = NULL;
        return;
    }

    switch (bakType)
    {
    case VT_BOOL:
        content.ValueArray = new Value[num];
        content.ValueArray[0].type = VT_BOOL;
        content.ValueArray[0].content.Bool = bakContent.Bool;
        content.ValueArray[0].num = 1;
        break;

    case VT_BOOL_ARRAY:
        content.ValueArray = new Value[num];
        if (bakContent.BoolArray)
        {
            for (int32_t i = 0; i < num; i++)
            {
                content.ValueArray[i].type = VT_BOOL;
                content.ValueArray[i].content.Bool = bakContent.BoolArray[i];
                content.ValueArray[i].num = 1;
            }
            delete[] bakContent.BoolArray;
        }
        break;

    case VT_CHAR:
        content.ValueArray = new Value[num];
        content.ValueArray[0].type = VT_CHAR;
        content.ValueArray[0].content.Char = bakContent.Char;
        content.ValueArray[0].num = 1;
        break;

    case VT_STRING:
        content.ValueArray = new Value[num];
        content.ValueArray[0].type = VT_STRING;
        content.ValueArray[0].content.String = bakContent.String;
        content.ValueArray[0].num = 1;
        break;

    case VT_STRING_ARRAY:
        content.ValueArray = new Value[num];
        if (bakContent.StringArray)
        {
            for (int32_t i = 0; i < num; i++)
            {
                content.ValueArray[i].type = VT_STRING;
                content.ValueArray[i].content.String = bakContent.StringArray[i];
                content.ValueArray[i].num = 1;
            }
            delete[] bakContent.StringArray;
        }
        break;

    case VT_INT:
        content.ValueArray = new Value[num];
        content.ValueArray[0].type = VT_INT;
        content.ValueArray[0].content.Int = bakContent.Int;
        content.ValueArray[0].num = 1;
        content.ValueArray[0].zero = zero;
        break;

    case VT_INT_ARRAY:
        content.ValueArray = new Value[num];
        if (bakContent.IntArray)
        {
            for (int32_t i = 0; i < num; i++)
            {
                content.ValueArray[i].type = VT_INT;
                content.ValueArray[i].content.Int = bakContent.IntArray[i];
                content.ValueArray[i].num = 1;
                content.ValueArray[i].zero = zero;
            }
            delete[] bakContent.IntArray;
        }
        break;

    case VT_UINT:
        content.ValueArray = new Value[num];
        content.ValueArray[0].type = VT_UINT;
        content.ValueArray[0].content.UInt = bakContent.UInt;
        content.ValueArray[0].num = 1;
        content.ValueArray[0].zero = zero;
        break;

    case VT_UINT_ARRAY:
        content.ValueArray = new Value[num];
        if (bakContent.UIntArray)
        {
            for (int32_t i = 0; i < num; i++)
            {
                content.ValueArray[i].type = VT_UINT;
                content.ValueArray[i].content.UInt = bakContent.UIntArray[i];
                content.ValueArray[i].num = 1;
                content.ValueArray[i].zero = zero;
            }
            delete[] bakContent.UIntArray;
        }
        break;

    case VT_DOUBLE:
        content.ValueArray = new Value[num];
        content.ValueArray[0].type = VT_DOUBLE;
        content.ValueArray[0].content.Double = bakContent.Double;
        content.ValueArray[0].num = 1;
        content.ValueArray[0].zero = zero;
        break;

    case VT_DOUBLE_ARRAY:
        content.ValueArray = new Value[num];
        if (bakContent.DoubleArray)
        {
            for (int32_t i = 0; i < num; i++)
            {
                content.ValueArray[i].type = VT_DOUBLE;
                content.ValueArray[i].content.Double = bakContent.DoubleArray[i];
                content.ValueArray[i].num = 1;
                content.ValueArray[i].zero = zero;
            }
            delete[] bakContent.DoubleArray;
        }
        break;

    case VT_POINT:
        content.ValueArray = new Value[num];
        content.ValueArray[0].type = VT_POINT;
        content.ValueArray[0].content.Point = bakContent.Point;
        content.ValueArray[0].num = 1;
        break;

    case VT_POINT_ARRAY:
        content.ValueArray = new Value[num];
        if (bakContent.PointArray)
        {
            for (int32_t i = 0; i < num; i++)
            {
                content.ValueArray[i].type = VT_POINT;
                content.ValueArray[i].content.Point = bakContent.PointArray[i];
                content.ValueArray[i].num = 1;
            }
            delete[] bakContent.PointArray;
        }
        break;

    default:
        break;
    }
}
